#include "BlobFinder.h"
#include "Range.h"
#include "BlobResult.h" 
#include <opencv/cv.h>

#include <QCheckBox>
#include <QVBoxLayout>
#include <QDebug>
#include <assert.h>

BlobFinder::BlobFinder() {
	display_center = Qt::Checked;
	min_blob_size = 0;
	max_num_blobs = 1;

	initSettings();	
}

void BlobFinder::initSettings() {
	settings = new QWidget();

	Range *num_blobs_slider = new Range(tr("Max num. of blobs"), settings);
	num_blobs_slider->setRange(0, 5);
	num_blobs_slider->setValue(1);

	Range *blob_size_slider = new Range(tr("Minimum blob size"), settings);
	blob_size_slider->setRange(0, 9999);
	blob_size_slider->setValue(100);

	QCheckBox *display_center_check = new QCheckBox(tr("Display Blob Centers"), settings);
	display_center_check->setCheckState(Qt::Checked);

	QVBoxLayout *layout = new QVBoxLayout;

	layout->addWidget(num_blobs_slider);
	layout->addWidget(blob_size_slider);
	layout->addWidget(display_center_check);

	settings->setLayout(layout);

	connect(num_blobs_slider, SIGNAL(valueChanged(int)), this, SLOT(changeNumBlobs(int)));
	connect(blob_size_slider, SIGNAL(valueChanged(int)), this, SLOT(changeBlobSize(int)));
	connect(display_center_check, SIGNAL(stateChanged(int)), this, SLOT(changeDisplaySetting(int)));
}

void BlobFinder::processPoint(ImageState *state) {
	if (!(state->image_type == GRAYSCALE || state->image_type == BINARY)) {
		qDebug() << "Not finding blobs - incompatible image type (" << state->image_type << ")";
		notifyListener(state);
		return;
	}
	CBlobResult blobs = CBlobResult(state->frame, NULL, 0);

	IplImage *out_image;
	out_image = cvCreateImage(cvGetSize(state->frame), IPL_DEPTH_8U, 3);

	cvMerge(state->frame, state->frame, state->frame, NULL, out_image);

	try {
		for(int i=0; i< max_num_blobs; i++) {
			CBlob current_blob;
		       	blobs.GetNthBlob(CBlobGetArea(), i, current_blob);
			if(current_blob.Area() < min_blob_size) break;
			current_blob.FillBlob(out_image, CV_RGB(255, 0, 0));
			if(display_center == Qt::Checked) {
				CvRect b_box = current_blob.GetBoundingBox();
				CvPoint p1 = cvPoint(b_box.x, b_box.y);
				CvPoint p2 = cvPoint(b_box.x+b_box.width, b_box.y+b_box.height);
				cvRectangle(out_image, p1, p2, cvScalar(0, 255, 0));
			}
		}
	} catch (...) {	}

	cvReleaseImage(&(state->frame));
	state->frame = out_image;

	assert(state->frame != 0);
	notifyListener(state);
}

void BlobFinder::changeNumBlobs(int num) {
	if(max_num_blobs != num) {
		qDebug() << "Blob num changed to " << num;
		max_num_blobs = num;
		emit numBlobsChanged(num);
	}
}
void BlobFinder::changeBlobSize(int size) {
	if(min_blob_size != size) {
		min_blob_size = size;
		emit blobSizeChanged(size);
	}
}
void BlobFinder::changeDisplaySetting(int state) {
	if(display_center != state) {
		display_center = state;
		emit displaySettingChanged(state);
	}
}
